home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 4 / MacFormat n. 4 (Spain) / MacFormat 4.bin / La ciudad del ShareWare / Desarrollo / OutOfPhase1.1 Source / OutOfPhase Folder / PcodeStack.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-26  |  10.9 KB  |  332 lines

  1. /* PcodeStack.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #define SHOW_ME_STACKELEMENT  /* we need to be able to see contents of StackElement */
  31. #include "PcodeStack.h"
  32. #include "Memory.h"
  33.  
  34.  
  35. #define INITIALNUMSTACKCELLS (32)
  36. #define STACKEXTENDSIZE (16)
  37.  
  38.  
  39. /* this structure remembers the parameters until evaluation is called for */
  40. struct ParamStackRec
  41.     {
  42.         StackElement*            InitialStack;
  43.         long                            NumElements;
  44.         long                            InitialStackSize;
  45.     };
  46.  
  47.  
  48. /* create a list of parameters that will lead to a function call */
  49. ParamStackRec*        NewParamStack(void)
  50.     {
  51.         ParamStackRec*    Stack;
  52.  
  53.         Stack = (ParamStackRec*)AllocPtrCanFail(sizeof(ParamStackRec),
  54.             "ParamStackRec");
  55.         if (Stack == NIL)
  56.             {
  57.              FailurePoint1:
  58.                 return NIL;
  59.             }
  60.         Stack->InitialStack = (StackElement*)AllocPtrCanFail(
  61.             INITIALNUMSTACKCELLS * sizeof(StackElement),"StackElement");
  62.         if (Stack->InitialStack == NIL)
  63.             {
  64.              FailurePoint2:
  65.                 ReleasePtr((char*)Stack);
  66.                 goto FailurePoint1;
  67.             }
  68.         Stack->NumElements = 0;
  69.         Stack->InitialStackSize = INITIALNUMSTACKCELLS;
  70.         return Stack;
  71.     }
  72.  
  73.  
  74. void                            DisposeParamStack(ParamStackRec* Stack)
  75.     {
  76.         long                        Scan;
  77.  
  78.         CheckPtrExistence(Stack);
  79.         for (Scan = Stack->NumElements - 1; Scan >= 0; Scan -= 1)
  80.             {
  81.                 PRNGCHK(Stack->InitialStack,&(Stack->InitialStack[Scan]),
  82.                     sizeof(Stack->InitialStack[Scan]));
  83.                 if ((Stack->InitialStack[Scan].ElementType == esArray)
  84.                     && (Stack->InitialStack[Scan].Data.ArrayHandle != NIL))
  85.                     {
  86.                         DisposeIfNotOnStack(Stack->InitialStack,Scan);
  87.                     }
  88.             }
  89.         ReleasePtr((char*)(Stack->InitialStack));
  90.         ReleasePtr((char*)Stack);
  91.     }
  92.  
  93.  
  94. void                            DisposeIfNotOnStack(StackElement* Stack, long StackPtr)
  95.     {
  96.         CheckPtrExistence(Stack);
  97.         ERROR(Stack[StackPtr].ElementType != esArray,PRERR(ForceAbort,
  98.             "DisposeIfNotOnStack:  top of stack isn't an array"));
  99.         ERROR(Stack[StackPtr].Data.ArrayHandle == NIL,PRERR(ForceAbort,
  100.             "DisposeIfNotOnStack:  array is NIL"));
  101.         CheckPtrExistence(Stack[StackPtr].Data.ArrayHandle);
  102.         CheckPtrExistence(Stack[StackPtr].Data.ArrayHandle->Array);
  103.         Stack[StackPtr].Data.ArrayHandle->RefCount -= 1; /* decrement reference count */
  104.         if (Stack[StackPtr].Data.ArrayHandle->RefCount == 0)
  105.             {
  106.                 /* reference count = no existing references */
  107.                 ReleasePtr((char*)(Stack[StackPtr].Data.ArrayHandle->Array));
  108.                 ReleasePtr((char*)(Stack[StackPtr].Data.ArrayHandle));
  109.                 Stack[StackPtr].Data.ArrayHandle = NIL;
  110.             }
  111.     }
  112.  
  113.  
  114. void                            DisposeIfOnStackOnlyOnce(StackElement* Stack, long StackPtr, long Where)
  115.     {
  116.         CheckPtrExistence(Stack);
  117.         ERROR(Stack[Where].ElementType != esArray,PRERR(ForceAbort,
  118.             "DisposeIfOnStackOnlyOnce:  top of stack isn't an array"));
  119.         ERROR(Stack[Where].Data.ArrayHandle == NIL,PRERR(ForceAbort,
  120.             "DisposeIfOnStackOnlyOnce:  array is NIL"));
  121.         CheckPtrExistence(Stack[Where].Data.ArrayHandle);
  122.         CheckPtrExistence(Stack[Where].Data.ArrayHandle->Array);
  123.         Stack[Where].Data.ArrayHandle->RefCount -= 1; /* decrement reference count */
  124.         if (Stack[Where].Data.ArrayHandle->RefCount == 0)
  125.             {
  126.                 /* reference count = no existing references */
  127.                 ReleasePtr((char*)(Stack[Where].Data.ArrayHandle->Array));
  128.                 ReleasePtr((char*)(Stack[Where].Data.ArrayHandle));
  129.                 Stack[Where].Data.ArrayHandle = NIL;
  130.             }
  131.     }
  132.  
  133.  
  134. MyBoolean                    AddIntegerToStack(ParamStackRec* Stack, long IntegerValue)
  135.     {
  136.         CheckPtrExistence(Stack);
  137.         if (Stack->NumElements == Stack->InitialStackSize)
  138.             {
  139.                 StackElement*        NewStack;
  140.  
  141.                 /* enlarge stack */
  142.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  143.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  144.                 if (NewStack == NIL)
  145.                     {
  146.                         return False;
  147.                     }
  148.                 Stack->InitialStack = NewStack;
  149.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  150.             }
  151.         Stack->InitialStack[Stack->NumElements].Data.Integer = IntegerValue;
  152.         Stack->InitialStack[Stack->NumElements].ElementType = esScalar;
  153.         Stack->NumElements += 1;
  154.         return True;
  155.     }
  156.  
  157.  
  158. MyBoolean                    AddFloatToStack(ParamStackRec* Stack, float FloatValue)
  159.     {
  160.         CheckPtrExistence(Stack);
  161.         if (Stack->NumElements == Stack->InitialStackSize)
  162.             {
  163.                 StackElement*        NewStack;
  164.  
  165.                 /* enlarge stack */
  166.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  167.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  168.                 if (NewStack == NIL)
  169.                     {
  170.                         return False;
  171.                     }
  172.                 Stack->InitialStack = NewStack;
  173.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  174.             }
  175.         Stack->InitialStack[Stack->NumElements].Data.Float = FloatValue;
  176.         Stack->InitialStack[Stack->NumElements].ElementType = esScalar;
  177.         Stack->NumElements += 1;
  178.         return True;
  179.     }
  180.  
  181.  
  182. MyBoolean                    AddDoubleToStack(ParamStackRec* Stack, double DoubleValue)
  183.     {
  184.         CheckPtrExistence(Stack);
  185.         if (Stack->NumElements == Stack->InitialStackSize)
  186.             {
  187.                 StackElement*        NewStack;
  188.  
  189.                 /* enlarge stack */
  190.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  191.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  192.                 if (NewStack == NIL)
  193.                     {
  194.                         return False;
  195.                     }
  196.                 Stack->InitialStack = NewStack;
  197.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  198.             }
  199.         Stack->InitialStack[Stack->NumElements].Data.Double = DoubleValue;
  200.         Stack->InitialStack[Stack->NumElements].ElementType = esScalar;
  201.         Stack->NumElements += 1;
  202.         return True;
  203.     }
  204.  
  205.  
  206. /* the ACTUAL array is added, so you no longer own it after this! */
  207. MyBoolean                    AddArrayToStack(ParamStackRec* Stack, void* Array)
  208.     {
  209.         CheckPtrExistence(Stack);
  210.         if (Stack->NumElements == Stack->InitialStackSize)
  211.             {
  212.                 StackElement*        NewStack;
  213.  
  214.                 /* enlarge stack */
  215.                 NewStack = (StackElement*)ResizePtr((char*)(Stack->InitialStack),
  216.                     (Stack->InitialStackSize + STACKEXTENDSIZE) * sizeof(StackElement));
  217.                 if (NewStack == NIL)
  218.                     {
  219.                         return False;
  220.                     }
  221.                 Stack->InitialStack = NewStack;
  222.                 Stack->InitialStackSize += STACKEXTENDSIZE;
  223.             }
  224.         if (Array != NIL)
  225.             {
  226.                 Stack->InitialStack[Stack->NumElements].Data.ArrayHandle =
  227.                     (ArrayHandleType*)AllocPtrCanFail(sizeof(ArrayHandleType),"ArrayHandleType");
  228.                 if (Stack->InitialStack[Stack->NumElements].Data.ArrayHandle == NIL)
  229.                     {
  230.                         return False;
  231.                     }
  232.                 Stack->InitialStack[Stack->NumElements].Data.ArrayHandle->Array = Array;
  233.                 Stack->InitialStack[Stack->NumElements].Data.ArrayHandle->RefCount = 1;
  234.             }
  235.          else
  236.             {
  237.                 Stack->InitialStack[Stack->NumElements].Data.ArrayHandle = NIL;
  238.             }
  239.         Stack->InitialStack[Stack->NumElements].ElementType = esArray;
  240.         Stack->NumElements += 1;
  241.         return True;
  242.     }
  243.  
  244.  
  245. long                            GetStackInteger(ParamStackRec* Stack, long Index)
  246.     {
  247.         CheckPtrExistence(Stack);
  248.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  249.             "GetStackInteger:  index out of range"));
  250.         ERROR(Stack->InitialStack[Index].ElementType != esScalar,PRERR(ForceAbort,
  251.             "GetStackInteger:  not a scalar value"));
  252.         return Stack->InitialStack[Index].Data.Integer;
  253.     }
  254.  
  255.  
  256. float                            GetStackFloat(ParamStackRec* Stack, long Index)
  257.     {
  258.         CheckPtrExistence(Stack);
  259.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  260.             "GetStackFloat:  index out of range"));
  261.         ERROR(Stack->InitialStack[Index].ElementType != esScalar,PRERR(ForceAbort,
  262.             "GetStackFloat:  not a scalar value"));
  263.         return Stack->InitialStack[Index].Data.Float;
  264.     }
  265.  
  266.  
  267. double                        GetStackLongDouble(ParamStackRec* Stack, long Index)
  268.     {
  269.         CheckPtrExistence(Stack);
  270.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  271.             "GetStackLongDouble:  index out of range"));
  272.         ERROR(Stack->InitialStack[Index].ElementType != esScalar,PRERR(ForceAbort,
  273.             "GetStackLongDouble:  not a scalar value"));
  274.         return Stack->InitialStack[Index].Data.Double;
  275.     }
  276.  
  277.  
  278. /* It returns the actual array, so you only get to use it on a loan basis */
  279. void*                            GetStackArray(ParamStackRec* Stack, long Index)
  280.     {
  281.         CheckPtrExistence(Stack);
  282.         ERROR((Index < 0) || (Index >= Stack->NumElements),PRERR(ForceAbort,
  283.             "GetStackArrayCopy:  index out of range"));
  284.         ERROR(Stack->InitialStack[Index].ElementType != esArray,PRERR(ForceAbort,
  285.             "GetStackArrayCopy:  not an array value"));
  286.         if (Stack->InitialStack[Index].Data.ArrayHandle == NIL)
  287.             {
  288.                 return NIL;
  289.             }
  290.          else
  291.             {
  292.                 CheckPtrExistence(Stack->InitialStack[Index].Data.ArrayHandle);
  293.                 CheckPtrExistence(Stack->InitialStack[Index].Data.ArrayHandle->Array);
  294.                 return Stack->InitialStack[Index].Data.ArrayHandle->Array;
  295.             }
  296.     }
  297.  
  298.  
  299. StackElement*            GetStackBase(ParamStackRec* Stack)
  300.     {
  301.         CheckPtrExistence(Stack);
  302.         return Stack->InitialStack;
  303.     }
  304.  
  305.  
  306. long                            GetStackInitialSize(ParamStackRec* Stack)
  307.     {
  308.         CheckPtrExistence(Stack);
  309.         return Stack->InitialStackSize;
  310.     }
  311.  
  312.  
  313. long                            GetStackNumElements(ParamStackRec* Stack)
  314.     {
  315.         CheckPtrExistence(Stack);
  316.         return Stack->NumElements;
  317.     }
  318.  
  319.  
  320. void                            SetStackInformation(ParamStackRec* Stack, long NewTotalSize,
  321.                                         long NewNumElements, StackElement* NewStackAddress)
  322.     {
  323.         CheckPtrExistence(Stack);
  324.         PRNGCHK(NewStackAddress,NewStackAddress,sizeof(StackElement) * NewTotalSize);
  325.         ERROR((NewNumElements < 0) || (NewNumElements > NewTotalSize),PRERR(ForceAbort,
  326.             "SetStackInformation:  parametric weirdness"));
  327.         ERROR(NewNumElements != Stack->NumElements,PRERR(ForceAbort,
  328.             "SetStackInformation:  initial stack pointer is different"));
  329.         Stack->InitialStack = NewStackAddress;
  330.         Stack->InitialStackSize = NewTotalSize;
  331.     }
  332.